# tests.py
#
# Copyright (c) 2009 Stephen Day
#
# This module is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php
#

import unittest, re
from wsgiref.util import application_uri
from webtest import TestApp
from werkzeug import Response
from urlminer import Resource, redirect
from paste import urlmap


class BlogPostApp(Resource):
   pattern = '\d{4}/\d{1,2}/\d{1,2}/(.+)'
   def GET(self,environ, start_response):
      res = Response('Blog post slug: %s' % self.mo.group(1))
      return res(environ, start_response)

class TagApp(Resource):
   pattern = 'tags/(\w+)'
   def GET(self,environ, start_response):
      res = Response('Tag: %s' % self.mo.group(1),
                     mimetype='text/html')
      return res(environ, start_response)   

class ArchiveListApp(Resource):
   pattern = '' #This matches a trailing slash 
   def GET(self,environ, start_response):
      res = Response('Archive list',
                     mimetype='text/html')
      return res(environ, start_response)


class ArchiveApp(Resource):
   children = [ArchiveListApp]
   pattern = 'archive'
   def GET(self,environ, start_response):
      res = Response('Archive home',
                     mimetype='text/html')
      return res(environ, start_response)

class BlogListMonthApp(Resource):
   pattern = '\d{4}/\d{1,2}'

   def GET(self,environ, start_response):
      res = Response('Blog list: %s'
                     % self.path_arg,
                     mimetype='text/html')
      return res(environ, start_response)

   def index(self, environ, start_response):
        location = application_uri(environ) + '/'
        if environ.get('QUERY_STRING'):
            location += '?' + environ['QUERY_STRING']
        res = redirect(location,status=301)
        return res(environ, start_response)

   def default(self,environ, start_response):
       if environ['PATH_INFO'] == '/':
          return self.GET(environ, start_response)
       else:
          return self.not_found(environ, start_response)

class AuthorApp(Resource):
   pattern = '(\w+)'
   def GET(self,environ, start_response):
      res = Response('Author: %s' % self.mo.groups(1))
      return res(environ, start_response)   

class AuthorsApp(Resource):
   children = [AuthorApp]
   pattern = 'authors'

   def GET(self,environ, start_response):
      res = Response('Author list',
                     mimetype='text/html')
      return res(environ, start_response)

   def index(self, environ, start_response):
        location = application_uri(environ) + '/'
        if environ.get('QUERY_STRING'):
            location += '?' + environ['QUERY_STRING']
        res = redirect(location,status=301)
        return res(environ, start_response)


   def default(self,environ, start_response):
       if environ['PATH_INFO'] == '/':
          return self.GET(environ, start_response)
       else:
          return self.not_found(environ, start_response)

  
class BlogApp(Resource):
   children = [ArchiveApp,BlogPostApp,BlogListMonthApp,TagApp,AuthorsApp]
   def GET(self,environ, start_response):
      res = Response('My Blog home',
                     mimetype='text/html')
      return res(environ, start_response)

   def POST(self,environ, start_response):
        location = application_uri(environ).rstrip('/') + '/2009/1/26/a-big-day'
        res = redirect(location,status=303)
        return res(environ, start_response)


class BlogTest(unittest.TestCase):
    """
    The url configuration for this test was roughly modelled after that of
    the zine blog engine <http://zine.pocoo.org/>

    /
    /archive
    /2009/1/11/a-blog-post
    /2009/01/
    /tags/announcements
    /authors/
    /authors/shday

    /
    /archive
    /archive/
    /\d{4}/\d{1,2}/\d{1,2}/(.+)
    /\d{4}/\d{1,2}
    /tags/(\w+)
    /authors
    /authors/(\w+)
    
    """

    def setUp(self):
       self.app = TestApp(BlogApp())
       self.base = ''
       
    def test_root(self):
        self.assertEquals(
            self.app.get(self.base).body, 'My Blog home')

    def test_redirect(self):
         self.assertEquals(
            self.app.get(self.base+'/archive').body,  'Archive home')
         self.assertEquals(
            self.app.get(self.base+'/archive/').body,  'Archive list')
         self.assertEquals(
            self.app.get(self.base+'/2008/12').follow().body,  'Blog list: 2008/12')

    def test_post(self):
        self.assertEquals(
            self.app.post(self.base).follow().body, 'Blog post slug: a-big-day')
        
    def test_terminal_slash(self):
        self.assertEquals(
            self.app.get(self.base+'/authors/').body, 'Author list')
        self.assertEquals(
            self.app.get(self.base+'/authors/shday').body, 'Author: shday')

    def test_multi_node(self):
        self.assertEquals(
            self.app.get(self.base+'/2008/12/24/zine-0-1-aldus-released').body,
            'Blog post slug: zine-0-1-aldus-released')       
        self.assertEquals(
            self.app.get(self.base+'/2008/12/').body, 'Blog list: 2008/12')
        self.assertEquals(
            self.app.get(self.base+'/tags/python').body, 'Tag: python')


class URLmapTest(BlogTest):
    """

    """

    def setUp(self):
       dispatcher = urlmap.URLMap()
       dispatcher['/blog'] = BlogApp()
       self.app = TestApp(dispatcher)
       self.base = '/blog'

class URLmapTest2(BlogTest):
    """

    """

    def setUp(self):
       dispatcher = urlmap.URLMap()
       dispatcher['/'] = BlogApp()
       self.app = TestApp(dispatcher)
       self.base = ''

       
class BlogApp2(BlogApp):
   pattern = 'blog'

class DispatchingApp(Resource):
   children = [BlogApp2]

class DispatchingAppTest(URLmapTest):
    """

    """

    def setUp(self):
       self.app = TestApp(DispatchingApp())
       self.base = '/blog'




class Boo(Resource):
   pattern = ''
   children = [ArchiveApp,BlogPostApp,BlogListMonthApp,TagApp,AuthorsApp]

class Foo(Boo):
   pass
   
class MiscApp(Foo):
   def GET(self,environ, start_response):
      res = Response('My MiscApp',
                     mimetype='text/html')
      return res(environ, start_response)

class MiscTest(unittest.TestCase):
    """

    """

    def setUp(self):
       self.app = TestApp(MiscApp())
       
    def test_inheritence(self):
        self.assertEquals(
            self.app.get('').body, 'My MiscApp')

def test_suite():
    return unittest.TestSuite((
        unittest.makeSuite(BlogTest),
        unittest.makeSuite(MiscTest),
        unittest.makeSuite(URLmapTest),
        unittest.makeSuite(URLmapTest2),
        unittest.makeSuite(DispatchingAppTest),
        ))        


def run_suite(verbosity=1):
    runner = unittest.TextTestRunner(verbosity=verbosity)
    runner.run(test_suite())

def _test():
    import doctest
    doctest.testmod()

if __name__ == "__main__":
    import sys
    args = sys.argv
    verbosity = 1
    if len(args) > 1:
        verbosity = args[1]
    run_suite(verbosity=verbosity)
    _test()
